package main

import "fmt"

// 基类
type Base struct {
}

func (b *Base) Func1() {
	fmt.Println("Base.Func1() was invoked!")
}

func (b *Base) Func2() {
	fmt.Println("Base.Func2() was invoked!")
}

type Derived struct {
	Base
}

func (d *Derived) Func2() {
	fmt.Println("Derived.Func2() was invoked!")
}

func (d *Derived) Func3() {
	fmt.Println("Derived.Func3() was invoked!")
}

// 非匿名
type Logger struct {
}
type NonWork struct {
	log Logger
}
type NonWork2 struct {
	log *Logger
}

func (Logger) Info(v interface{}) {

	if t, ok := v.(int); ok {
		fmt.Println(t, "is an int value.")
	}
	//	switch v.(type) {
	//	case int:
	//		fmt.Println(v, "is an int value.")
	//	}
}

// 匿名
type Work struct {
	Logger
}
type Work2 struct {
	*Logger
}

func main() {
	// 子类
	//	d := &Derived{}
	//	d.Func1()      // Base.Func1() was invoked!
	//	d.Base.Func1() // Base.Func1() was invoked!

	//	d.Func2()      // Derived.Func2() was invoked!
	//	d.Base.Func2() // Base.Func2() was invoked!

	//	d.Func3() // Derived.Func3() was invoked!

	// 非匿名组合初始化方式
	//	var nwk = NonWork{log: Logger{}}
	//	var nwwk = NonWork{Logger{}}
	//	//...and so on
	//	var nwk2 = NonWork2{log: new(Logger)}
	//	var nwwk2 = NonWork2{new(Logger)}
	//	var nwwk2 = NonWork2{&Logger{}}

	// 匿名组合初始化方式
	//	var wk = Work{Logger{}}
	//	var wwk = Work{Logger: Logger{}}
	//	var wk2 = Work2{new(Logger)}
	//	var wwk23 = Work2{Logger: &Logger{}}
	//	var wwk2 = Work2{&Logger{}}
}
